﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HalconDotNet;

namespace MyHalconWindow
{
    public partial class MyHalconWindowControl
    {
        private int mImgWidth = 2448;
        private int mImgHeight = 2048;

        private int mWinWidth;
        private int mWinHeight;
        private HObject mHImage = null;

        public void setImgSize(int width, int height)
        {
            if (width < 1 || height < 1)
                throw new Exception("请输入正确的图像尺寸");
            mImgWidth = width;
            mImgHeight = height;

        }


        private bool zoom(double ratio, int posX, int posY)
        {
            return zoom(mWindow, ratio, posX, posY);
        }
        public bool zoom(HWindow window, double ratio, int posX, int posY)
        {
            lock (this)
            {
                int row1 = 0;
                int column1 = 0;
                int row2 = 0;
                int column2 = 0;
                window.GetPart(out row1, out column1, out row2, out column2);
                int d_row = (int)(row2 * (ratio - 1));
                int d_column = (int)(column2 * (ratio - 1));

                double ration11 = (double)mWinWidth / mWinHeight;

                int dx1, dx2, dy1, dy2;
                double ratioX1 = (double)posX / mWinWidth * 2 * ration11;
                double ratioX2 = (2 - (double)posX / mWinWidth * 2) * ration11;
                double ratioY1 = (double)posY / mWinHeight * 2 / ration11;
                double ratioY2 = (2 - (double)posY / mWinHeight * 2) / ration11;
                dx1 = (int)(ratioX1 * d_row);
                dx2 = (int)(ratioX2 * d_row);
                dy1 = (int)(ratioY1 * d_column);
                dy2 = (int)(ratioY2 * d_column);

                int rowResult1 = row1 + dy1;
                int columnResult1 = column1 + dx1;
                int rowResult2 = row2 - dy2;
                int columnResult2 = column2 - dx2;

                if ((rowResult2 < rowResult1) || (columnResult2 < columnResult1))
                    return false;

                window.SetPart(rowResult1, columnResult1, rowResult2, columnResult2);

            }

            return true;
        }

        public bool zoom_move(int posX, int posY)
        {
            return zoom_move(mWindow, posX, posY);
        }

        private int xd, yd, wd, hd, mouseXpos, mouseYpos;     //鼠标按下是的窗口显示数据setiamgepart
        public bool zoom_move(HWindow window, int posX, int posY)
        {
            //int x = 0;
            //int y = 0;
            //int width = 0;
            //int height = 0;
            //window.GetPart(out y, out x, out height, out width);
            int dw = wd - xd;
            double ratio = (double)dw / mWinWidth;

            int dx = posX - mouseXpos;
            int dy = posY - mouseYpos;


            int dx1 = (int)(dx * ratio);
            int dy1 = (int)(dy * ratio);
            Console.WriteLine(ratio);
            window.SetPart(yd - dy1, xd - dx1, hd - dy1, wd - dx1);
            return true;
        }

        //记录鼠标按下时，窗口的part状态
        public void setMouseDownStatus(int posX, int posY)
        {
            setMouseDownStatus(mWindow, posX, posY);
        }
        public void setMouseDownStatus(HWindow window, int posX, int posY)
        {
            mouseXpos = posX;
            mouseYpos = posY;
            window.GetPart(out yd, out xd, out hd, out wd);
        }


        public bool zoom_fit_window()
        {
            return zoom_fit_window(mWindow);
        }


        public bool zoom_fit_window(HWindow window)
        {
            int width_i = mImgWidth;
            int height_i = mImgHeight;
            int x1, y1, w1, h1;

            double x_r = (double)mWinWidth / width_i;
            double y_r = (double)mWinHeight / height_i;

            if(x_r < y_r)
            {
                //x轴满铺
                x1 = 0;
                w1 = width_i;
                int height = (int)(mWinHeight * mImgWidth / mWinWidth);
                y1 = (int)((mImgHeight - height) / 2);
                h1 = y1 + height;

            }
            else
            {
                y1 = 0;
                h1 = height_i;
                int width = (int)(mWinWidth * mImgHeight / mWinHeight);
                x1 = (mImgWidth - width) / 2;
                w1 = width + x1;
            }

            window.SetPart(y1, x1, h1, w1);

            return true;
        }


        public void reload_image()
        {
            reload_image(mWindow);
        }


        

        public void show_image(string path)
        {
            HObject img;
            HOperatorSet.ReadImage(out img, path);
            show_image(img);
        }

        public void show_image(HObject image)
        {
            if (isEmpty(image))
                return;

            if (!isEmpty(mHImage))
            {
                HTuple isSameTuple;
                //加载模板图片出错， todo
                HOperatorSet.TestEqualObj(image, mHImage, out isSameTuple);

                //如果相等
                if ((int)(isSameTuple) != 0) return;
            }

            if (!isEmpty(mHImage)) {
                mHImage.Dispose();
            }
            HOperatorSet.DispObj(image, mWindow);
            mHImage = image;
        }

        public List<MyRegion> getShowRegionList()
        {
            return mDrawRegionList;
        }

        public List<MyContour> getMatchContourList()
        {
            return mMatchContoursList;
        }

        public void reload_image(HWindow window)
        {
            if (!isEmpty(mHImage)) HOperatorSet.DispObj(mHImage, window);

            if (mHImage != null && mHImage.Key != IntPtr.Zero)
            {
                try
                {
                    HOperatorSet.DispObj(mHImage, window);
                }
                catch (HalconException ex)
                {
                    string msg = "重载图片错误。" + ex.ToString();
                }

            }


            if (mDrawRegionList.Count > 0)
            {
                foreach (MyRegion myRegion in mDrawRegionList)
                {
                    if (!isEmpty(myRegion.region))
                    {
                        dispObj(myRegion.region, myRegion.color, myRegion.isFill);
                    }
                }
            }

            if (mMatchContoursList.Count > 0)
            {
                foreach (MyContour myContour in mMatchContoursList)
                {
                    if (!isEmpty(myContour.contour))
                    {
                        //HOperatorSet.DispObj(myContour.contour, window);
                        dispObj(myContour.contour, myContour.color, myContour.isFill);
                    }
                }
            }

        }


        public void clear_all_match_contours()
        {
            if (mMatchContoursList.Count > 0)
            {
                foreach (MyContour myContour in mMatchContoursList)
                {
                    if (!isEmpty(myContour.contour)) myContour.contour.Dispose();
                }
                mMatchContoursList.Clear();
            }
        }

        public void clear_all_draw_regions()
        {
            if (mDrawRegionList.Count > 0)
            {
                foreach (MyRegion myRegion in mDrawRegionList)
                {
                    if (!isEmpty(myRegion.region)) myRegion.region.Dispose();
                }
                mDrawRegionList.Clear();
            }
        }



        public void clear_all_region_and_contours()
        {
            clear_all_region_and_contours(mWindow);
        }



        public void clear_all_region_and_contours(HWindow window)
        {
            clear_all_match_contours();
            clear_all_draw_regions();

        }


        public void dispObj(HObject obj, string color, bool isFill)
        {
            string drawStyle = isFill ? "fill" : "margin";
            mWindow.SetDraw(drawStyle);
            mWindow.SetColor(color);
            HOperatorSet.DispObj(obj, mWindow);

        }

    }
}
